////1. any ,  any 的含义是：任意类型，⼀旦将变量类型限制为 any ，那就意味着放弃了对该变量的类型检查
// 明确的表示a的类型是 any —— 【显式的any】
let aa: any
// 以下对a的赋值，均⽆警告
aa = 100
aa = '你好'
aa = false
// 没有明确的表示b的类型是any，但TS主动推断出来b是any —— 隐式的any
let bb
//以下对b的赋值，均⽆警告
bb = 100
bb = '你好'
bb = false

/* 注意点：any类型的变量，可以赋值给任意类型的变量 */
let cc: any
cc = 9
let x: string
x = cc // ⽆警告
console.log(x)




//2. unknown , unknown 的含义是：未知类型，适⽤于：起初不确定数据的具体类型，要后期才能确定, unknown 可以理解为⼀个类型安全的 any 。
let unk: unknown
unk = 99
unk = "xxx"
unk = false
console.log(unk)

let unk_str: string
//unknown
// unk_str = unk  //警告：不能将类型“unknown”分配给类型“string”
//any
let unk_any: any
unk_any = "xx"
unk_str = unk_any

//unknown 会强制开发者在使⽤之前进⾏类型检查，从⽽提供更强的类型安全性。 
//第⼀种⽅式：加类型判断
if (typeof unk == "string") {
    unk_str = unk
}

//第⼆种⽅式：加断⾔
unk_str = unk as string

//第三种⽅式：加断⾔
unk_str = <string>unk

//读取 any 类型数据的任何属性都不会报错，⽽ unknown 正好与之相反。
let unk_str1: string
unk_str1 = 'hello'
unk_str1.toUpperCase() //⽆警告

let unk_str2: any
unk_str2 = 'hello'
unk_str2.toUpperCase() //⽆警告

let unk_str3: unknown
unk_str3 = 'hello';
(unk_str3 as string).toUpperCase() //警告：“unk_str3”的类型为“未知”





//3. never , never 的含义是：任何值都不是，即：不能有值，例如 undefined 、 null 、 '' 、 0 都不⾏！

//1. ⼏乎不⽤ never 去直接限制变量，因为没有意义，例如：
let never_a: never
// 以下对a的所有赋值都会有警告
// never_a = 1
// never_a = true
// never_a = undefined
// never_a = null

//never 用来定义一个函数不能有返回值 (void)
// function neverDemo(): never {
//     //空函数报错，是因为函数执行完毕会默认返回一个值(undefined) => 一个永远不能成功执行的函数

//     // neverDemo()
//     // throw new Error("")
// }

//2. never ⼀般是 TypeScript 主动推断出来的，例如：
// 指定a的类型为string
let never_b: string
// 给a设置⼀个值
never_b = 'hello'
if (typeof never_b === 'string') {
    console.log(never_b.toUpperCase())
} else {
    console.log(never_b) // TypeScript会推断出此处的a是never，因为没有任何⼀个值符合此处的逻辑
}

//3. never 也可⽤于限制函数的返回值
// 限制throwError函数不需要有任何返回值，任何值都不⾏，像undeifned、null都不⾏
function throwError(str: string): never {
    throw new Error('程序异常退出:' + str)
}
